package org.microframework.base.core.security.config;

import org.microframework.base.core.security.interceptor.GlobalSecurityInterceptor;
import org.microframework.base.core.security.interceptor.SecurityInterceptor;
import org.microframework.base.core.security.properties.SecurityProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Web MVC安全配置
 * 
 * 负责注册安全拦截器
 */
@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class WebMvcSecurityConfig implements WebMvcConfigurer {
    
    private static final Logger log = LoggerFactory.getLogger(WebMvcSecurityConfig.class);
    
    /**
     * 默认排除路径
     */
    private static final String[] DEFAULT_EXCLUDE_PATTERNS = {
    };
    
    @Autowired
    private SecurityProperties securityProperties;
    
    @Override
    public void addInterceptors(@NonNull InterceptorRegistry registry) {
        // 注册全局安全拦截器
        GlobalSecurityInterceptor globalInterceptor = getGlobalSecurityInterceptor();
        if (globalInterceptor != null && securityProperties.getGlobalInterceptor().isEnabled()) {
            // 获取配置的排除路径
            String[] configExcludePatterns = securityProperties.getGlobalInterceptor().getExcludePatterns();
            
            // 合并默认排除路径和配置的排除路径
            String[] allExcludePatterns;
            if (configExcludePatterns != null && configExcludePatterns.length > 0) {
                allExcludePatterns = new String[DEFAULT_EXCLUDE_PATTERNS.length + configExcludePatterns.length];
                System.arraycopy(DEFAULT_EXCLUDE_PATTERNS, 0, allExcludePatterns, 0, DEFAULT_EXCLUDE_PATTERNS.length);
                System.arraycopy(configExcludePatterns, 0, allExcludePatterns, DEFAULT_EXCLUDE_PATTERNS.length, configExcludePatterns.length);
                log.info("全局安全拦截器排除路径: {}", StringUtils.arrayToCommaDelimitedString(allExcludePatterns));
            } else {
                allExcludePatterns = DEFAULT_EXCLUDE_PATTERNS;
                log.info("全局安全拦截器使用默认排除路径: {}", StringUtils.arrayToCommaDelimitedString(DEFAULT_EXCLUDE_PATTERNS));
            }
            
            // 注册拦截器
            registry.addInterceptor(globalInterceptor)
                    .addPathPatterns("/**")
                    .excludePathPatterns(allExcludePatterns)
                    .order(globalInterceptor.getOrder());
            
            log.info("已注册全局安全拦截器，优先级: {}, 调试模式: {}", 
                    globalInterceptor.getOrder(), globalInterceptor.isDebug());
        }
        
        // 注册安全拦截器
        SecurityInterceptor securityInterceptor = getSecurityInterceptor();
        if (securityInterceptor != null && securityProperties.getInterceptor().isEnabled()) {
            // 获取配置的排除路径
            String[] configExcludePatterns = securityProperties.getInterceptor().getExcludePatterns();
            
            // 合并默认排除路径和配置的排除路径
            String[] allExcludePatterns;
            if (configExcludePatterns != null && configExcludePatterns.length > 0) {
                allExcludePatterns = new String[DEFAULT_EXCLUDE_PATTERNS.length + configExcludePatterns.length];
                System.arraycopy(DEFAULT_EXCLUDE_PATTERNS, 0, allExcludePatterns, 0, DEFAULT_EXCLUDE_PATTERNS.length);
                System.arraycopy(configExcludePatterns, 0, allExcludePatterns, DEFAULT_EXCLUDE_PATTERNS.length, configExcludePatterns.length);
                log.info("安全拦截器排除路径: {}", StringUtils.arrayToCommaDelimitedString(allExcludePatterns));
            } else {
                allExcludePatterns = DEFAULT_EXCLUDE_PATTERNS;
                log.info("安全拦截器使用默认排除路径: {}", StringUtils.arrayToCommaDelimitedString(DEFAULT_EXCLUDE_PATTERNS));
            }
            
            // 注册拦截器
            registry.addInterceptor(securityInterceptor)
                    .addPathPatterns("/**")
                    .excludePathPatterns(allExcludePatterns)
                    .order(securityInterceptor.getOrder());
            
            log.info("已注册安全拦截器，优先级: {}, 要求登录: {}, 权限检查: {}", 
                    securityInterceptor.getOrder(), 
                    securityProperties.getInterceptor().isRequiresLogin(),
                    securityProperties.getInterceptor().isEnablePermissionCheck());
        }
    }
    
    /**
     * 全局安全拦截器
     */
    @Bean
    @ConditionalOnProperty(value = "micro.security.global-interceptor.enabled", havingValue = "true", matchIfMissing = true)
    public GlobalSecurityInterceptor getGlobalSecurityInterceptor() {
        GlobalSecurityInterceptor interceptor = new GlobalSecurityInterceptor();
        
        // 从配置中读取设置
        SecurityProperties.GlobalInterceptor config = securityProperties.getGlobalInterceptor();
        interceptor.setEnabled(config.isEnabled());
        interceptor.setOrder(config.getOrder());
        interceptor.setDebug(config.isDebug());
        interceptor.setAddSecurityHeaders(config.isAddSecurityHeaders());
        interceptor.setMonitorSlowRequests(config.isMonitorSlowRequests());
        interceptor.setSlowRequestThreshold(config.getSlowRequestThreshold());
        
        return interceptor;
    }
    
    /**
     * 安全拦截器
     */
    @Bean
    @ConditionalOnProperty(value = "micro.security.interceptor.enabled", havingValue = "true", matchIfMissing = false)
    public SecurityInterceptor getSecurityInterceptor() {
        SecurityInterceptor interceptor = new SecurityInterceptor();
        
        // 从配置中读取设置
        SecurityProperties.Interceptor config = securityProperties.getInterceptor();
        interceptor.setOrder(config.getOrder());
        return interceptor;
    }
} 